package com.dslplatform.json;

import com.dslplatform.json.runtime.Settings;
import org.junit.Assert;
import org.junit.Test;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.*;

public class BigIntegerTest {

	@Test
	public void testSmallValues() throws IOException {
		BigInteger[] values = new BigInteger[]{
				BigInteger.ZERO,
				BigInteger.valueOf(1),
				BigInteger.valueOf(-1),
				BigInteger.valueOf(Integer.MAX_VALUE),
				BigInteger.valueOf(12345678901234567L),
				BigInteger.valueOf(Long.MAX_VALUE)
		};
		DslJson dslJson = new DslJson();
		JsonWriter jw = dslJson.newWriter();
		JsonReader jr = dslJson.newReader();
		for (BigInteger v : values) {
			jw.reset();
			NumberConverter.serialize(v, jw);
			jr.process(jw.getByteBuffer(), jw.size());
			jr.read();
			BigInteger d = NumberConverter.deserializeBigInteger(jr);
			Assert.assertEquals(v, d);
		}
	}

	@Test
	public void testRandomValues() throws IOException {
		Random rnd = new Random();
		DslJson dslJson = new DslJson();
		JsonWriter jw = dslJson.newWriter();
		JsonReader jr = dslJson.newReader();
		for(int i = 1;i < 500; i++) {
			BigInteger v = new BigInteger(i, rnd);
			jw.reset();
			NumberConverter.serialize(v, jw);
			jr.process(jw.getByteBuffer(), jw.size());
			jr.read();
			BigInteger d = NumberConverter.deserializeBigInteger(jr);
			Assert.assertEquals(v, d);
		}
	}


	private void prepareJson(JsonReader<Object> reader, byte[] input) throws IOException {
		reader.process(input, input.length);
		reader.read();
		reader.read();
		reader.fillName();
		reader.read();
	}

	private BigInteger checkError(JsonReader<Object> reader, String error) {
		BigInteger res = BigInteger.ZERO;
		try {
			res = NumberConverter.deserializeBigInteger(reader);
			if (error != null) Assert.fail("Expecting " + error);
		} catch (Exception ex) {
			Assert.assertTrue(ex.getMessage().contains(error));
		}
		return res;
	}

	@Test
	public void zeroParsing() throws IOException {
		final DslJson<Object> dslJson = new DslJson<>();
		final JsonReader<Object> jr = dslJson.newReader(new byte[0]);

		byte[] doubleZero = "{\"x\":00}".getBytes("UTF-8");
		byte[] negativeZero = "{\"x\":-00}".getBytes("UTF-8");
		byte[] zeroWithSpace = "{\"x\":0 }".getBytes("UTF-8");
		byte[] negativeZeroWithSpace = "{\"x\":-0 }".getBytes("UTF-8");

		byte[][] input = {doubleZero, negativeZero, zeroWithSpace, negativeZeroWithSpace};

		for(byte[] it : input) {
			prepareJson(jr, it);
			Assert.assertEquals(BigInteger.ZERO, checkError(jr, null));
		}
	}

	@Test
	public void wrongSpaceParsing() throws IOException {
		final DslJson<Object> dslJson = new DslJson<>();
		final JsonReader<Object> jr = dslJson.newReader(new byte[0]);

		byte[] doubleZero = "{\"x\":0 0}".getBytes("UTF-8");
		byte[] doubleDot1 = "{\"x\":0.0.}".getBytes("UTF-8");
		byte[] doubleDot2 = "{\"x\":0..0}".getBytes("UTF-8");
		byte[] dotNoNumber1 = "{\"x\":.0}".getBytes("UTF-8");
		byte[] dotNoNumber2 = "{\"x\":0.}".getBytes("UTF-8");

		byte[][] input = {doubleZero, doubleDot1, doubleDot2, dotNoNumber1, dotNoNumber2};

		for(byte[] it : input) {
			prepareJson(jr, it);
			checkError(jr, "Error parsing number at position: 5");
		}
	}

	@Test
	public void largeNumbers() throws IOException {
		final DslJson<Object> dslJson = new DslJson<>(Settings.withRuntime()
				.unknownNumbers(JsonReader.UnknownNumberParsing.LONG_AND_DOUBLE)
				.allowArrayFormat(true)
				.includeServiceLoader());
		final JsonReader<Object> jr = dslJson.newReader(new byte[0]);
		String jsonString = "[603563865116368502029653754475327546482613643136576633826461308426053463377,603563865116023616762120730389649508501078028598961728144325922904633250336,603563865116310774460097715773537007917950785408793488039768006967116739602,603563865116281451299322818803065178457259212843210227469584345568789573316,603563865116069113009137185565789021222975874988591912063150777006311140769,603563865116162170502286865282838298092694033757951505339787724395541370419,603563865116271652594265816636943210966523413993147186711015440130449539353,603563865116346693719026380070006420172992317194893077112483330276337718581,603563865116311859077230346617958243682170470642527860847858757012082684942,603563865116000358632460241699809306899550439806170316136079034303802137808,603563865116368492752676164205719523597501306935299460246082235330573692196,603563865116375093924040961267079881430020576829760038485909319949819074150,603563865116303055737000656852243176966437402676835863694182607459984524844,603563865116314434003092425482132833374590719207607130048547494333893355596,603563865116321395752714630962854189904625712738351545866776465227849872062,603563865116176366065658880177608098588822246327698476528041562716316587470,603563865116221117288637739598061744077558862811083795746987007257482772346,603563865116300110184344652504159660308592227718255707538200168670075018975,603563865116399354062745428587506812340275635287846762717152749751987471418,603563865116142379728444996656107650650360157920003174012263578358669189062,603563865116203656802645783013057944952749662349894648810862204089970977754,603563865116230714262051340160470838014851946891776174389923717551504610094,603563865116106375049478230220283864570806621646962225354380354636553729691,603563865116268968027776505571881555947715692952759439396695135760266145156,603563865116372302290182657143252542834177393668036962778818138927356644615,603563865116348562137658937885450834286397427670219201780462997675735127987,603563865116181634126026704222430389646154643792515786887328241636001677083,603563865116283764637779413131220106422835777014423393309498354021606520095,603563865116383516925788349862750379776249869190773633096911753987278026466,603563865116351402673991645752633936665661790780675590271811973438062592438,603563865116167923173844320789452586677323287023324380741830731495981194743,603563865116028198368592588672001034273053491522788970078350521503376954113,603563865116077482273737883531642656683648068064388004485177737854611337234,603563865116027464696184048016584026339393482669278842314681629936833473511,603563865116296237212181129280681272490957660415919530731289836612040535539,603563865116395440700967273369274907390993430008438664693605844102023942867,603563865115996409683268417738355383209489929271403124186237313858293649546,603563865116304276002475368158632726607584739955306232740861625474769332706,603563865116038092166238023420784929422971411142332265655152271305610546453,603563865116406054384994581248975418595830699431299759064366379523064992557,603563865116056225215524981435190960979329094101681359954415624685254929682,603563865116029424054316793539598871040022454144380200526850660543619506929,603563865116356582203338040836370155817956433503276476672106867844837408308,603563865116386679998656526353682143768177900389208975978860286782453288325,603563865116075075444513291907139901289515664796494174409586846711493017133,603563865116124567035346764503356144270056522188089430341067300684923137239,603563865116211860405615700696664064073870861350692594426554334401206595716,603563865116232654765086404091080176691956770019140396925582193525798929456,603563865116265351111940177790190935894076519581367543315807984002945364002,603563865116099641330314793661740221970993936958353755777174098384831252457,603563865116158154488963928051124344255383724349375808252883508585566901151,603563865116272844083095275282744772703964947095154704120962761423078980660,603563865116312272939177481193567542882959190396997305205174949976051657227,603563865116377283250772552362403683656608735531540897092024395806324483519,603563865116271509957794410898607662844121462438631062817276338072526449293,603563865116162504664395015053879829320933157444549048573984347021096927372,603563865116148853319600673866947184236347236657912062355933007745902855359,603563865116024797096278699498669993485042617264268468807621400384474118609,603563865116275497135179242103161313092380227898782793652013697195735434582,603563865116206486552003554251491457345311925964515522322047801338414114623,603563865116111782122519348078339072223743314220332792661991071695193547979,603563865116161623676981390772788453561900622222606128963415290920858056466,603563865116300573737940375044793654798396072928648902815681988859964823657,603563865116097587591832382172092344614018858195068937127418978648735194388,603563865116106302875899117425451742906322348924518276030380253921528613241,603563865116399476039130088193335793345985017587668384192146671222121813066,603563865116310704173624585683252456708382273244717332011074938913069656156,603563865116091321973582268405168662385039021846518631079558727753960301232,603563865116044929090610283860276932992496659884248695909937080638940396838,603563865116005994616968097488414836405854853656741809614480984023961506396,603563865116369052735498666344188454461762668768405558988288569773048433338,603563865116016104145097407575696819629937274065338400205404931365707234579,603563865116000501565423766236024763096720149801915299871197382126749585080,603563865116086457317748409802271981182016813427158828879937148520131959008,603563865116395855992281170724310597941715357209603383425448261929775474417,603563865116110320695279646794654137294711770879080196463836883542062307957,603563865116148634772766202080881428776123588443618211878201216417112156337,603563865116019019660273540129020778095237363127724123578281785091631334097,603563865116363474922024203721198326695745180684049825539080375205261553129,603563865116163600083524558378337685429004695493868453010038334571004420116,603563865116204590002021533836734679784802312107973818638185586940454781406,603563865116303890969221733193697004243468831489835733738166180198778709681,603563865116028064172561851675283997650125972357924868791085534558625257095,603563865116311465889155981989009666620181011237490023458959756687499516477,603563865116064661088070949150545591385858004430735389287227835395634012245,603563865116144365476879711167854680381478011606089248053883811211020675390,603563865116117072646035247327492463737271267991771791154375032570828937760,603563865116197644277936303557362839652405800429573728125575269548262494368,603563865116403154785107604794551937312228537096667808020519666963054824733,603563865116115875352652381121069156701331385809482983900073148122467134168,603563865116203478934228580297036581655589931205616367135951083866717796468,603563865116369317839918373072759718121606305302078395026368953430513915036,603563865116202518854579991170497883206621131260460622345892010972620520477,603563865116048525612620566669228523129627510464716924897105056348637047069,603563865116108867331184363152662781088857797024039523901394979442240145070,603563865116144090669069979555125083214788936650314120200919663257896672377,603563865115999549364624975850172310536625277732877741760501243972477594128,603563865116336831776729882834748204000203813370449883600022648611745928347,603563865116256901947715084515260487185877949689692016111523087305522584155,603563865116405109829363251683218745849549457187770807220812332762833042558,603563865116121015335474651378249648741629400543031106857090099193637788364,603563865116211625408073323027499642061296785065980419910522784883245481683,603563865116275491491024907181525701776576550422301935399038770726694808289,603563865116283505655325188477632667567171339253868906226293105438156282852,603563865116280963372349595733079597576735365342731066493649006092377345173,603563865116149562436456165019323610262324243824332040390356638335005015767,603563865116325190879564673458343449764773840397807745682813898089596208108,603563865116173137036181343289755746739428727486204454225869690530586558984,603563865116254446702433155510622794716096483680682369171674009328194530044,603563865116277587203733250381841980816373886650064282105002882748287343774,603563865116381554868024193371709637842098311037299780396271095933541932546,603563865116121359468711774904639194153800592060492214255976625325856091880,603563865116189648742438189858486985331528856653233962650796547553446542944,603563865116055879404454736783423660715403996769947215302954581255557046467,603563865116284983768584483384761409360198125199012318344603803654589758860,603563865116085957248891762455214805867746009790980947415972029533302695276,603563865116189064650824682628379527709168389011030663997666857338220326648,603563865116046987907366515766326364026536955454569583477818780190941277504,603563865116324954870444014397652790545438285533592898146141077623656062658,603563865116155596595853842394199509751704629540866993298696939973659700231,603563865116349841866504463523359878235970667166428691264506156019092821377,603563865116128328009912175905471428974473196666504646371142839492269259062,603563865116211018637148517925046649980808681158349740425885343059918032172,603563865116239884763316978963458874761368289803951045039073006775063562700,603563865116027644717394898803353413818439670304225323679453819197105871059,603563865116076808490271412968175336113637317301940842810981315905838798525,603563865116217368925371640873176709263997663516819082298369627069877451117,603563865116067785487995195362495619890170764567126971677548976549307199022,603563865116189496492626898703769354482552287816729003650804632396727941595,603563865116389327851251390181823163769154081794947900838881368100663560802,603563865116355325386030212683503528585718544610887699853170235700323085047,603563865116388997105007555824806661342382664485172248098563917073414776554,603563865116153424573514922007918591574533649357683696300295034697589358557,603563865116189855302846803799006937663765382543129707582009492553186983554,603563865116051368680221616346414342861452352864049985423695742805627295198,603563865116219780142405604346819733692142377164158950356947054839504958097,603563865116224703697682948392379979401268399892742010078437273499214857561,603563865116368666186307249383428868384031682213102941275229356769982917303,603563865116104176149060650738365115791737749465078871625675975271998762840,603563865116068867715480144957410650009769704566745654292702687295316814749,603563865116278893596233929948494411588964989191044078775736905855360191530,603563865116176213668894521101899340602260976337019661418405148657319319428,603563865116016592843992003132976832079286158795121747524002181765425978534,603563865116050213939915449413927268057315296447895388436370603487934243877,603563865116252935402721966823373928387754843287788794372983936394596020556,603563865116257663753310064911522993568804819916245805066162806943063316682,603563865116034532501656521230657891034033835426268503395706165233637775318,603563865116218214548579025451669750669510709721720014000199022479435515388,603563865116115492927393272595335360164652489580713286655077928366472583046,603563865116305540380068517913444366702574874702283097655744841764930926965,603563865116394345856541770180035009765799658582846189184957785556268166804,603563865116058497210487596558492671199260719303445972878123883375735642150,603563865116085033210412390088809587861242839225449137258588259427098300588,603563865116279460211474370620463224720591344759719616729595039848563286217,603563865116376007278535606419976871893624641785861426304555247230804911021,603563865116074154973089505760765984364559703059343374717535930378113108062,603563865116017129937577243708435483589347994470299007210747591585888346662,603563865116045635674064697688262958212407765773707548695095964005063683738,603563865116094155288506812565328132727997992616047899626234724981676421540,603563865116269209247437544177209141365003088762545760647261394026338760926,603563865116140628748496786173371394951907257424696280024260961066317465219,603563865116012609998371858452445150058523715278628428107162827207736022348,603563865116070715335658017227752889424318650437633926995415911787201687001,603563865116385139641329328125803966004993025136334092066504252618052526583,603563865116152911246303501568924473425786548211990969064606717657463882665,603563865116341562759592238946862587311346688212974359811427103840911430703,603563865116252368351616745508809407038982746195225999213385394306233658358,603563865116169653470687194564982626660530421000756918705424833347493488237,603563865116133815069302552909412816126215047444472953518329525181978910305,603563865116182556014816120637020849539340362050428930503120023962664909434,603563865116244637291724037125323816308968995439310203760207527005639834027,603563865116242826810103928247772205127107481808831288868836151906821697681,603563865116158655353273381218258285978308320292324956243059304404591736505,603563865116108393745491288177697882655441933639963470000635338118566726918,603563865116182067025441069112241187917171952725074666343295964367805764457,603563865116107402352805125224935286227734601747662995748643532511812299314,603563865116049340009029961451590384099377913776730106401182549553340586149,603563865116194128698044385418338872991826172664065834344989987708809562416,603563865116163380896197820938421902483230546886196953407370289660851774453,603563865116339946968877578097965897761094345003539238385459171740610751874,603563865116302768559036006214551268122591243268343524472585719004245907140,603563865116077140627211790170094343831684542229977858413732905275328377738,603563865116019895548546970151619209482220878290138453644988641718062489644,603563865116198417133768047927776371578864865811578288357587422590113650137,603563865116296594453454886702796182899867859906388900273100623114518301090,603563865115996768167129921611101946772285745067249630101355168141803207965,603563865116388509923887984948626558485673628174840313771925716776814851019,603563865116326423889903713282071526182590582553369728635790969309165014414,603563865116307183277694360744330876597775234541534818986590056864519594721,603563865116250925907502743084931698360320257100840491213754331442419016780,603563865116370794080430746865394971222192953308370261149221481463188933149,603563865116113254672480692978406581307304895429361580167217002551699311862,603563865116293693346144152907494980471027690895292401965147465526725609157,603563865116045914581575655805899853361022130194992309097126557285815726390,603563865116164428417970562131204300723439935472756131242641961000900666227,603563865116227340554455823098851033027206367929302273740886920983923826061,603563865116137487771747488735590022878766928207063278862180794693454500329,603563865116290721342669411869381594366779774472290935025626518720478875909,603563865116059522615104861362041718530537337661081119514692269940774779946,603563865116104165756147893632846389230427052840877761186003668757618712514,603563865116023240841205863679247180086119596766650271962172111379690994998,603563865116264873622623257549324060604960159089594504915251932147774067327,603563865116388208206089215610778867926417112290729511801484119670717815802,603563865116111501919888680977828186166111329471086195123743470637701035307,603563865116384569493854024584332945334060516596665256168555429740119845299,603563865116159251621041981378522636357857396566504691987072939558079509477,603563865116333061308532000161539776693055281119642027699171080195713493768,603563865116026540821621391905483180609583735349218953949398575495608508212,603563865116160016295771126613145677669142827727246052279215126175326326658,603563865116405294179220953524267807839901306863597164496699958455860119255,603563865116325182690099949296481652330125382048060420575327981643286538620,603563865116184034111412065472391624069362597042205934659308061378246653171,603563865116246254626242129459897381645798657602060021787857052704095299927,603563865116227403538276428707106734480429164694899737843030216968689657064,603563865116285999008993359481908675300336814640230358610328184241050544988,603563865116229814585750777366959692281217640264485021428520617279155290353,603563865116075139779242317119880867736253071161200615680861022787084140706,603563865116049798779963705168923196350070158882579562454620566739678881283,603563865116160654578310292105379796533684235426066182380821007903960683587,603563865116193755710262046151203171921995828875176893814093615075681118515,603563865116021694605452831639608756380920186184945295119205359420669974091,603563865116205391346306384722872207572813390642024111516801973176439754511,603563865116253949076253119041418079378568041955871919410711731840679028288,603563865116161406736443532133993128027347212695477087817174954520387244194,603563865116127403926822693764441856456928727801300116532950417343183128098,603563865116078809580120596685473588659477234879283663134139379304189367662,603563865116215049340502533303903267283352510698803647049640145764823138491,603563865116129659829373872185520644768230580831036865539832603422717616497,603563865116015726106227516411574989521947620373450274062345436267651357128,603563865116382474556835280071939649284515098444449392719633587117877260177,603563865116104934394311715213220717651328734575275630102032340474106207824,603563865116229673148815735567560486338983047626215075117692884677258192076,603563865116084920092579110259942372176848728561287324386544368097709134211,603563865116321482128206465264586794604642210431559113048815252033716780766,603563865116231517187426105647631856029753858460713276318367208078330210012,603563865116098517860875722671972671006885510313323353853352008073089493664,603563865116130390583952651121652809061008223955027828390072749158530675594,603563865116340632056062664065652496882579457708191429976335133868380331333,603563865116100180657153280458513511040171709687652370868356983274768670612,603563865116303245278910640410736026230897787142405561279795915000551122638,603563865116020126652386273423455786161347035483500484706716728507771903820,603563865116015169397005976551739327059537783451683074279035271495366757614,603563865116078518506856136881128441584232058246283387342019574532567096771,603563865116107771332915089173051340265537947809629147127884850810405964086,603563865116149913338544256762176117221461159720933482098209922871502072283,603563865116218652765109008014277260255114162850981404077671035404551722254,603563865116046599961567124846499611565644015151484037417585419330494963075,603563865116337664308858699936972611015799171590410454967924840582841415953,603563865116372030990426739390047798172872676871878552055862604707554619548,603563865116339284208288982619727420172335845729824914281174478880116136014,603563865116284707597240450726742398329118393800880150731618178265038366253,603563865116156622730508748681450450464646248121310869414936507803779691053,603563865116285588503580728677580461961521253250138391745702259209020982966,603563865116253709264688584917500196262419319805531599489192443272296572374,603563865116342507035310542695926110492467085880272034684011935318925254860,603563865116241398335905088771032518514539592511861104338259633000924494189,603563865116150804553620170047561962236454893390604677756004756372369893776,603563865116211087849411888779318260827464461589021892851189482524377188678,603563865116172599787941603768429529933209527826801570443165021961278445013,603563865116080662895120176622394327433362177511198806192041937244023996480,603563865116372278757617120164210745002331766956528337699487383296113168019,603563865116311222246009360776319085041504811714726554807058353890225049944,603563865116047668378221801056280728878205885983183652095188961837517399985,603563865116281003895755238399452344972615421296727981805300395011521967628,603563865116183986737077079746029228873833011315816712157946978406969596186,603563865116193892708090483767562262635484228033903452627697075330796765705,603563865116383927600205495387634121118667747876199082351266366518525494534,603563865116191793998773819423717923750753303301163667516867858675204822452,603563865116319851199685988041326070710169473514375958724059922474533160014,603563865116361713372311633013635707262804888878165103984788204739881255892,603563865116321089612712971821533847474045211928557818133752060758082113892,603563865116099824101391656772687396232359380986182900317800372492173175270,603563865116021768209471441986189992626955443946374117286801913184966899687,603563865116110917540592783158508675617224074349039418397392434230266941671,603563865116359442870629801802794226426999898001548419546690162064113813409,603563865116384444077839487808792648800429159565056442755790002844154644178,603563865116016899320900992036871725827643440437364891896638359660468956785,603563865116308445725285092397970370868927075626137549940377714436481451025,603563865116000284184340711318855758541096557976796677678814485047613787422,603563865116152305588609207108458801991005366917371386632221594662566796499,603563865116139885620414481816365343860190786217336200804515561739866216823,603563865116405408474055381778928460126874179894094834717633413888214980337,603563865116339396987635345553613624183008099199725695751228572463744133002,603563865116083217959798071853391034144099715998969070320056684475034016455,603563865116202685921276229626810714805699673631987206778563675148011738629,603563865116157642067548426303355243215254256635125189500684594715839250004,603563865116044626484480784378199325533038559775259416163275895840055182602,603563865116220466775156362632840605514209097364061662816368287002053380477,603563865116378150560212591415104377382791060219391494162896557576461890292,603563865116220050292530158802807344807621429108370715573919649379679863080,603563865116229789903241613501050288758676903223140112091979121572928144644,603563865116028041252048759886104961097705803117819017048428005413622518567,603563865116123368903317478762956752327642494903195780865068341215201127466,603563865116095856949349169644844360984005734939467405378690397020520266424,603563865116339594360590504582651205203350353953878669166557686766657631046,603563865116160872872209533567267571436485183516541246768072206114878126510,603563865116311849236738602537072456216264792779591719997121744064119305429,603563865116143703028666511793464496058519115221306567817784529455070699959,603563865116111706619122322531278848989607450851075042237572271729215754953,603563865116201151044930637591873876280997727310367892919828718924606611971]";
		List<BigInteger> numbers = dslJson.deserializeList(BigInteger.class, new ByteArrayInputStream(jsonString.getBytes(StandardCharsets.UTF_8)));
		Assert.assertEquals(300, numbers.size());
		String[] actualNumbers = jsonString.substring(1, jsonString.length() - 1).split(",");
		for (int i = 0; i < actualNumbers.length; i++) {
			BigInteger bi = new BigInteger(actualNumbers[i]);
			Assert.assertEquals(bi, numbers.get(i));
		}
	}
}